package com.qny.ai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qny.ai.dto.role.RoleCreateRequest;
import com.qny.ai.dto.role.RoleUpdateRequest;
import com.qny.ai.entity.AppRole;
import com.qny.ai.entity.RoleRating;
import com.qny.ai.entity.UserRoleFavorite;
import com.qny.ai.exception.BusinessException;
import com.qny.ai.common.ErrorCode;
import com.qny.ai.mapper.AppRoleMapper;
import com.qny.ai.mapper.RoleRatingMapper;
import com.qny.ai.mapper.UserRoleFavoriteMapper;
import com.qny.ai.service.RoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class RoleServiceImpl implements RoleService {

    private final AppRoleMapper appRoleMapper;
    private final RoleRatingMapper roleRatingMapper;
    private final UserRoleFavoriteMapper userRoleFavoriteMapper;

    @Override
    public Long createRole(Long creatorId, RoleCreateRequest request) {
        log.info("创建角色 - 创建者ID: {}, 角色名称: {}", creatorId, request.getName());
        AppRole role = new AppRole();
        role.setName(request.getName());
        role.setCreatorId(creatorId);
        role.setIsSystem(0);
        role.setStatus(StringUtils.hasText(request.getStatus()) ? request.getStatus() : "PUBLISHED");
        role.setPrivacy(StringUtils.hasText(request.getPrivacy()) ? request.getPrivacy() : "PRIVATE");
        role.setAvatarUrl(request.getAvatarUrl());
        role.setBackground(request.getBackground());
        role.setPersonality(request.getPersonality());
        role.setLanguageStyle(request.getLanguageStyle());
        role.setPromptTemplate(request.getPromptTemplate());
        role.setOpeningLine(request.getOpeningLine());
        role.setParametersJson(request.getParametersJson());
        role.setDescription(request.getDescription());
        role.setTags(request.getTags());
        role.setDefaultVoiceType(StringUtils.hasText(request.getDefaultVoiceType()) ? request.getDefaultVoiceType() : "qiniu_zh_female_wwxkjx");
        role.setCategory(request.getCategory());
        int inserted = appRoleMapper.insert(role);
        if (inserted != 1) {
            throw new BusinessException(ErrorCode.SERVER_ERROR.getCode(), "创建角色失败");
        }
        log.info("角色创建成功 - ID: {}, 创建者ID: {}", role.getId(), role.getCreatorId());
        return role.getId();
    }

    @Override
    public boolean updateRole(RoleUpdateRequest request) {
        AppRole role = appRoleMapper.selectById(request.getId());
        if (role == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND);
        }
        if (request.getName() != null) role.setName(request.getName());
        if (request.getAvatarUrl() != null) role.setAvatarUrl(request.getAvatarUrl());
        if (request.getDescription() != null) role.setDescription(request.getDescription());
        if (request.getBackground() != null) role.setBackground(request.getBackground());
        if (request.getPersonality() != null) role.setPersonality(request.getPersonality());
        if (request.getLanguageStyle() != null) role.setLanguageStyle(request.getLanguageStyle());
        if (request.getPromptTemplate() != null) role.setPromptTemplate(request.getPromptTemplate());
        if (request.getOpeningLine() != null) role.setOpeningLine(request.getOpeningLine());
        if (request.getParametersJson() != null) role.setParametersJson(request.getParametersJson());
        if (request.getTags() != null) role.setTags(request.getTags());
        if (request.getStatus() != null) role.setStatus(request.getStatus());
        if (request.getPrivacy() != null) role.setPrivacy(request.getPrivacy());
        return appRoleMapper.updateById(role) == 1;
    }

    @Override
    public AppRole getById(Long id) {
        return appRoleMapper.selectById(id);
    }

    @Override
    public boolean deleteById(Long id) {
        return appRoleMapper.deleteById(id) == 1;
    }

    @Override
    public Page<AppRole> pageList(int pageNo, int pageSize, String keyword) {
        Page<AppRole> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<AppRole> qw = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(keyword)) {
            qw.like(AppRole::getName, keyword);
        }
        return appRoleMapper.selectPage(page, qw);
    }

    @Override
    public Page<AppRole> search(String keyword, String status, String privacy, String sortBy, boolean asc, int pageNo, int pageSize) {
        Page<AppRole> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<AppRole> qw = new LambdaQueryWrapper<>();

        // 只搜索公开状态的角色
        qw.eq(AppRole::getStatus, "PUBLISHED").eq(AppRole::getPrivacy, "PUBLIC");

        // 关键词搜索：支持名字、描述、标签的模糊搜索
        if (StringUtils.hasText(keyword)) {
            qw.and(wrapper -> wrapper
                    .like(AppRole::getName, keyword)
                    .or()
                    .like(AppRole::getDescription, keyword)
                    .or()
                    .like(AppRole::getTags, keyword)
            );
        }

        // 额外的状态和隐私过滤（如果需要）
        if (StringUtils.hasText(status)) {
            qw.eq(AppRole::getStatus, status);
        }
        if (StringUtils.hasText(privacy)) {
            qw.eq(AppRole::getPrivacy, privacy);
        }

        // 排序字段白名单
        if ("usageCount".equals(sortBy)) {
            qw.orderBy(true, asc, AppRole::getUsageCount);
        } else if ("averageRating".equals(sortBy)) {
            qw.orderBy(true, asc, AppRole::getAverageRating);
        } else if ("ratingCount".equals(sortBy)) {
            qw.orderBy(true, asc, AppRole::getRatingCount);
        } else if ("createdAt".equals(sortBy)) {
            qw.orderBy(true, asc, AppRole::getCreatedAt);
        } else if ("shareCount".equals(sortBy)) {
            qw.orderBy(true, asc, AppRole::getShareCount);
        } else {
            // 默认按创建时间倒序
            qw.orderByDesc(AppRole::getCreatedAt);
        }

        return appRoleMapper.selectPage(page, qw);
    }

    @Override
    public Page<AppRole> getMyRoles(Long creatorId, int pageNo, int pageSize) {
        log.info("获取我的角色 - 创建者ID: {}, 页码: {}, 页大小: {}", creatorId, pageNo, pageSize);
        Page<AppRole> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<AppRole> qw = new LambdaQueryWrapper<>();
        qw.eq(AppRole::getCreatorId, creatorId);
        qw.orderByDesc(AppRole::getCreatedAt);
        
        Page<AppRole> result = appRoleMapper.selectPage(page, qw);
        log.info("获取我的角色结果 - 总数: {}, 当前页记录数: {}", result.getTotal(), result.getRecords().size());
        return result;
    }

    @Override
    public List<AppRole> getHotRoles() {
        log.info("获取热门角色");
        LambdaQueryWrapper<AppRole> qw = new LambdaQueryWrapper<>();
        qw.eq(AppRole::getPrivacy, "PUBLIC");
        qw.orderByDesc(AppRole::getUsageCount);
        qw.orderByDesc(AppRole::getFavoriteCount);
        qw.orderByDesc(AppRole::getAverageRating);
        qw.last("LIMIT 6");
        
        List<AppRole> hotRoles = appRoleMapper.selectList(qw);
        log.info("获取热门角色结果 - 数量: {}", hotRoles.size());
        return hotRoles;
    }

    @Override
    public boolean incrementUsage(Long roleId) {
        AppRole role = appRoleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "角色不存在");
        }

        // 增加使用量
        role.setUsageCount(role.getUsageCount() + 1);
        return appRoleMapper.updateById(role) == 1;
    }

    @Override
    public Page<AppRole> getFavoriteRoles(Long userId, int pageNo, int pageSize) {
        log.info("获取收藏角色 - 用户ID: {}, 页码: {}, 页大小: {}", userId, pageNo, pageSize);
        
        // 先查询用户收藏的角色ID列表
        LambdaQueryWrapper<UserRoleFavorite> favoriteQw = new LambdaQueryWrapper<>();
        favoriteQw.eq(UserRoleFavorite::getUserId, userId);
        favoriteQw.orderByDesc(UserRoleFavorite::getCreatedAt);
        
        Page<UserRoleFavorite> favoritePage = new Page<>(pageNo, pageSize);
        Page<UserRoleFavorite> favoriteResult = userRoleFavoriteMapper.selectPage(favoritePage, favoriteQw);
        
        if (favoriteResult.getRecords().isEmpty()) {
            // 没有收藏的角色，返回空页面
            Page<AppRole> emptyPage = new Page<>(pageNo, pageSize);
            emptyPage.setTotal(0);
            return emptyPage;
        }
        
        // 提取角色ID列表
        List<Long> roleIds = favoriteResult.getRecords().stream()
                .map(UserRoleFavorite::getRoleId)
                .collect(java.util.stream.Collectors.toList());
        
        // 查询角色详情
        LambdaQueryWrapper<AppRole> roleQw = new LambdaQueryWrapper<>();
        roleQw.in(AppRole::getId, roleIds);
        roleQw.eq(AppRole::getPrivacy, "PUBLIC"); // 只显示公开的角色
        
        List<AppRole> roles = appRoleMapper.selectList(roleQw);
        
        // 按照收藏顺序排序
        List<AppRole> sortedRoles = new ArrayList<>();
        for (UserRoleFavorite favorite : favoriteResult.getRecords()) {
            roles.stream()
                    .filter(role -> role.getId().equals(favorite.getRoleId()))
                    .findFirst()
                    .ifPresent(sortedRoles::add);
        }
        
        // 构建分页结果
        Page<AppRole> result = new Page<>(pageNo, pageSize);
        result.setRecords(sortedRoles);
        result.setTotal(favoriteResult.getTotal());
        result.setPages(favoriteResult.getPages());
        result.setCurrent(favoriteResult.getCurrent());
        result.setSize(favoriteResult.getSize());
        
        log.info("获取收藏角色结果 - 总数: {}, 当前页记录数: {}", result.getTotal(), result.getRecords().size());
        return result;
    }

    @Override
    public boolean publishRole(Long roleId, Long userId) {
        log.info("发布角色 - 角色ID: {}, 用户ID: {}", roleId, userId);
        AppRole role = appRoleMapper.selectById(roleId);
        if (role == null) {
            log.warn("角色不存在 - 角色ID: {}", roleId);
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "角色不存在");
        }
        if (!role.getCreatorId().equals(userId)) {
            log.warn("无权限发布角色 - 角色ID: {}, 用户ID: {}, 创建者ID: {}", roleId, userId, role.getCreatorId());
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "无权限发布此角色");
        }
        
        // 发布到角色广场：将隐私设置为PUBLIC
        role.setPrivacy("PUBLIC");
        int updated = appRoleMapper.updateById(role);
        log.info("角色发布结果 - 角色ID: {}, 更新行数: {}", roleId, updated);
        return updated == 1;
    }

    @Override
    public boolean unpublishRole(Long roleId, Long userId) {
        log.info("停止发布角色 - 角色ID: {}, 用户ID: {}", roleId, userId);
        AppRole role = appRoleMapper.selectById(roleId);
        if (role == null) {
            log.warn("角色不存在 - 角色ID: {}", roleId);
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "角色不存在");
        }
        if (!role.getCreatorId().equals(userId)) {
            log.warn("无权限停止发布角色 - 角色ID: {}, 用户ID: {}, 创建者ID: {}", roleId, userId, role.getCreatorId());
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "无权限停止发布此角色");
        }
        
        // 停止发布：将隐私设置为PRIVATE
        role.setPrivacy("PRIVATE");
        int updated = appRoleMapper.updateById(role);
        log.info("角色停止发布结果 - 角色ID: {}, 更新行数: {}", roleId, updated);
        return updated == 1;
    }

    @Override
    public Page<AppRole> searchRoles(String keyword, String status, String privacy, String category, String sortBy, Boolean asc, int pageNo, int pageSize) {
        log.info("搜索角色 - 关键词: {}, 状态: {}, 隐私: {}, 分类: {}, 排序: {}, 页码: {}, 页大小: {}",
                keyword, status, privacy, category, sortBy, pageNo, pageSize);
        Page<AppRole> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<AppRole> qw = new LambdaQueryWrapper<>();

        // 只搜索公开角色（由PRIVACY字段控制）
        qw.eq(AppRole::getPrivacy, "PUBLIC");

        // 分类筛选
        if (StringUtils.hasText(category) && !"all".equals(category)) {
            qw.eq(AppRole::getCategory, category);
        }

        if (StringUtils.hasText(keyword)) {
            qw.and(wrapper -> wrapper
                    .like(AppRole::getName, keyword)
                    .or()
                    .like(AppRole::getDescription, keyword)
                    .or()
                    .like(AppRole::getTags, keyword)
            );
        }

        if (StringUtils.hasText(status)) {
            qw.eq(AppRole::getStatus, status);
        }

        if (StringUtils.hasText(privacy)) {
            qw.eq(AppRole::getPrivacy, privacy);
        }

        // 排序
        if (StringUtils.hasText(sortBy)) {
            boolean isAsc = asc != null && asc;
            switch (sortBy) {
                case "usageCount":
                    qw.orderBy(true, isAsc, AppRole::getUsageCount);
                    break;
                case "averageRating":
                    qw.orderBy(true, isAsc, AppRole::getAverageRating);
                    break;
                case "favoriteCount":
                    qw.orderBy(true, isAsc, AppRole::getFavoriteCount);
                    break;
                default:
                    qw.orderByDesc(AppRole::getCreatedAt);
            }
        } else {
            qw.orderByDesc(AppRole::getCreatedAt);
        }

        Page<AppRole> result = appRoleMapper.selectPage(page, qw);
        log.info("搜索角色结果 - 总数: {}, 当前页记录数: {}", result.getTotal(), result.getRecords().size());
        return result;
    }

    @Override
    public AppRole getPublicRole(Long roleId) {
        log.info("获取公共角色详情 - 角色ID: {}", roleId);
        LambdaQueryWrapper<AppRole> qw = new LambdaQueryWrapper<>();
        qw.eq(AppRole::getId, roleId);
        qw.eq(AppRole::getPrivacy, "PUBLIC");

        AppRole role = appRoleMapper.selectOne(qw);
        if (role != null) {
            log.info("获取公共角色详情成功 - 角色ID: {}, 角色名称: {}", roleId, role.getName());
        } else {
            log.warn("公共角色不存在 - 角色ID: {}", roleId);
        }
        return role;
    }

    @Override
    public boolean toggleFavorite(Long roleId, Long userId) {
        log.info("切换角色收藏状态 - 角色ID: {}, 用户ID: {}", roleId, userId);

        // 检查角色是否存在且为公开状态
        AppRole role = appRoleMapper.selectById(roleId);
        if (role == null) {
            log.warn("角色不存在 - 角色ID: {}", roleId);
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "角色不存在");
        }
        if (!"PUBLIC".equals(role.getPrivacy())) {
            log.warn("角色未公开，无法收藏 - 角色ID: {}, 隐私设置: {}", roleId, role.getPrivacy());
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "角色未公开，无法收藏");
        }

        // 检查是否已收藏
        LambdaQueryWrapper<UserRoleFavorite> qw = new LambdaQueryWrapper<>();
        qw.eq(UserRoleFavorite::getUserId, userId);
        qw.eq(UserRoleFavorite::getRoleId, roleId);
        UserRoleFavorite existing = userRoleFavoriteMapper.selectOne(qw);

        if (existing != null) {
            // 取消收藏
            int deleted = userRoleFavoriteMapper.deleteById(existing.getId());
            if (deleted == 1) {
                // 更新角色收藏数
                role.setFavoriteCount(Math.max(0, (role.getFavoriteCount() != null ? role.getFavoriteCount() : 0) - 1));
                appRoleMapper.updateById(role);
                log.info("取消收藏成功 - 角色ID: {}, 用户ID: {}", roleId, userId);
                return false; // 返回false表示已取消收藏
            }
        } else {
            // 添加收藏
            UserRoleFavorite favorite = UserRoleFavorite.builder()
                    .userId(userId)
                    .roleId(roleId)
                    .createdAt(LocalDateTime.now())
                    .build();
            int inserted = userRoleFavoriteMapper.insert(favorite);
            if (inserted == 1) {
                // 更新角色收藏数
                role.setFavoriteCount((role.getFavoriteCount() != null ? role.getFavoriteCount() : 0) + 1);
                appRoleMapper.updateById(role);
                log.info("添加收藏成功 - 角色ID: {}, 用户ID: {}", roleId, userId);
                return true; // 返回true表示已添加收藏
            }
        }

        log.warn("收藏操作失败 - 角色ID: {}, 用户ID: {}", roleId, userId);
        return false;
    }

    @Override
    public List<RoleRating> getRoleReviews(Long roleId, int pageNo, int pageSize) {
        log.info("获取角色评价 - 角色ID: {}, 页码: {}, 页大小: {}", roleId, pageNo, pageSize);
        Page<RoleRating> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<RoleRating> qw = new LambdaQueryWrapper<>();
        qw.eq(RoleRating::getRoleId, roleId);
        qw.orderByDesc(RoleRating::getCreatedAt);

        Page<RoleRating> result = roleRatingMapper.selectPage(page, qw);
        log.info("获取角色评价结果 - 角色ID: {}, 评价数量: {}", roleId, result.getRecords().size());
        return result.getRecords();
    }

    @Override
    public boolean addRoleRating(Long roleId, Long userId, Integer rating, String comment) {
        log.info("添加角色评价 - 角色ID: {}, 用户ID: {}, 评分: {}", roleId, userId, rating);

        // 检查角色是否存在且为公开状态
        AppRole role = appRoleMapper.selectById(roleId);
        if (role == null) {
            log.warn("角色不存在 - 角色ID: {}", roleId);
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "角色不存在");
        }
        if (!"PUBLIC".equals(role.getPrivacy())) {
            log.warn("角色未公开，无法评价 - 角色ID: {}, 隐私设置: {}", roleId, role.getPrivacy());
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "角色未公开，无法评价");
        }

        // 检查是否已经评价过
        LambdaQueryWrapper<RoleRating> qw = new LambdaQueryWrapper<>();
        qw.eq(RoleRating::getRoleId, roleId);
        qw.eq(RoleRating::getUserId, userId);
        RoleRating existing = roleRatingMapper.selectOne(qw);

        if (existing != null) {
            log.warn("用户已评价过该角色 - 角色ID: {}, 用户ID: {}", roleId, userId);
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "您已经评价过该角色");
        }

        // 添加评价
        RoleRating roleRating = RoleRating.builder()
                .roleId(roleId)
                .userId(userId)
                .rating(rating)
                .comment(comment)
                .createdAt(LocalDateTime.now())
                .build();

        int inserted = roleRatingMapper.insert(roleRating);
        if (inserted == 1) {
            // 更新角色平均评分
            updateRoleAverageRating(roleId);
            log.info("添加评价成功 - 角色ID: {}, 用户ID: {}", roleId, userId);
            return true;
        }

        log.warn("添加评价失败 - 角色ID: {}, 用户ID: {}", roleId, userId);
        return false;
    }

    @Override
    public boolean updateRoleRating(Long ratingId, Long userId, Integer rating, String comment) {
        log.info("更新角色评价 - 评价ID: {}, 用户ID: {}, 评分: {}", ratingId, userId, rating);

        RoleRating existing = roleRatingMapper.selectById(ratingId);
        if (existing == null) {
            log.warn("评价不存在 - 评价ID: {}", ratingId);
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "评价不存在");
        }
        if (!existing.getUserId().equals(userId)) {
            log.warn("无权限更新评价 - 评价ID: {}, 用户ID: {}, 评价用户ID: {}", ratingId, userId, existing.getUserId());
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "无权限更新此评价");
        }

        existing.setRating(rating);
        existing.setComment(comment);
        existing.setCreatedAt(LocalDateTime.now());

        int updated = roleRatingMapper.updateById(existing);
        if (updated == 1) {
            // 更新角色平均评分
            updateRoleAverageRating(existing.getRoleId());
            log.info("更新评价成功 - 评价ID: {}, 用户ID: {}", ratingId, userId);
            return true;
        }

        log.warn("更新评价失败 - 评价ID: {}, 用户ID: {}", ratingId, userId);
        return false;
    }

    @Override
    public boolean deleteRoleRating(Long ratingId, Long userId) {
        log.info("删除角色评价 - 评价ID: {}, 用户ID: {}", ratingId, userId);

        RoleRating existing = roleRatingMapper.selectById(ratingId);
        if (existing == null) {
            log.warn("评价不存在 - 评价ID: {}", ratingId);
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "评价不存在");
        }
        if (!existing.getUserId().equals(userId)) {
            log.warn("无权限删除评价 - 评价ID: {}, 用户ID: {}, 评价用户ID: {}", ratingId, userId, existing.getUserId());
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "无权限删除此评价");
        }

        Long roleId = existing.getRoleId();
        int deleted = roleRatingMapper.deleteById(ratingId);
        if (deleted == 1) {
            // 更新角色平均评分
            updateRoleAverageRating(roleId);
            log.info("删除评价成功 - 评价ID: {}, 用户ID: {}", ratingId, userId);
            return true;
        }

        log.warn("删除评价失败 - 评价ID: {}, 用户ID: {}", ratingId, userId);
        return false;
    }

    /**
     * 更新角色平均评分
     */
    private void updateRoleAverageRating(Long roleId) {
        log.info("更新角色平均评分 - 角色ID: {}", roleId);

        LambdaQueryWrapper<RoleRating> qw = new LambdaQueryWrapper<>();
        qw.eq(RoleRating::getRoleId, roleId);
        List<RoleRating> ratings = roleRatingMapper.selectList(qw);

        if (ratings.isEmpty()) {
            // 没有评价，设置为0
            AppRole role = appRoleMapper.selectById(roleId);
            if (role != null) {
                role.setAverageRating(BigDecimal.ZERO);
                appRoleMapper.updateById(role);
            }
            return;
        }

        // 计算平均分
        double sum = ratings.stream().mapToInt(RoleRating::getRating).sum();
        double average = sum / ratings.size();

        AppRole role = appRoleMapper.selectById(roleId);
        if (role != null) {
            role.setAverageRating(new BigDecimal(Math.round(average * 10.0) / 10.0)); // 保留一位小数
            appRoleMapper.updateById(role);
            log.info("角色平均评分更新 - 角色ID: {}, 平均分: {}", roleId, role.getAverageRating());
        }
    }
}